﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;

namespace ClipboardTranslator
{
    public partial class MainForm : Form
    {
        const int WM_DRAWCLIPBOARD = 0x0308;
        const int WM_CHANGECBCHAIN = 0x030D;

        [DllImport("user32")]
        static public extern IntPtr SetClipboardViewer(IntPtr hWnd);

        [DllImport("user32")]
        static public extern bool ChangeClipboardChain(IntPtr hWnd);

        [DllImport("user32", CharSet = CharSet.Unicode)]
        static public extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32")]
        static public extern bool FlashWindow(IntPtr hWnd, bool bInvert);

        const int double_copy_to_clipboard_interval = 1500;

        IntPtr next_clipboard_viewer = IntPtr.Zero;

        Properties.Settings settings = new Properties.Settings();

        string url = null;

        string balloon_url = null;

        bool result_link_clicked = false;

        ResultForm result_form = null;

        bool should_save = false;

        bool default_location = false;

        string prev_clipboard_text = "";

        int last_copy_to_clipboard_tick_count = 0;

        bool can_close = false;

        bool loading = true;

        FormWindowState last_window_state;

        public enum BalloonClickAction 
        { 
            [Description("None")]
            None,
            [Description("Show web page")]
            ShowWebPage,
            [Description("Show tool tip")]
            ShowToolTip,
            [Description("Show form")]
            ShowForm 
        }

        public MainForm()
        {
            InitializeComponent();
            last_window_state = WindowState;
        }

        public Properties.Settings Settings { get { return settings; } }

        public void Navigate(string text)
        {
            comboBoxText.Text = text;
        }

        public ComboBox.ObjectCollection RuntimeHistory { get { return comboBoxText.Items; } }

        private void MainForm_Load(object sender, EventArgs e)
        {
            notifyIcon.Tag = false;

            textBoxPrefix.LostFocus += new EventHandler(textUrl_TextChanged);
            comboBoxText.LostFocus += new EventHandler(textUrl_TextChanged);
            textBoxPostfix.LostFocus += new EventHandler(textUrl_TextChanged);

            List<string> profiles = new List<string>();
            LoadUserProfiles(profiles);
            LoadApplicationProfiles(profiles);
            comboBoxProfile.Reset(profiles.ToArray());

            foreach (string profile in profiles)
            {
                ToolStripMenuItem menu_item = new ProfileToolStripMenuItem(profile);
                menu_item.Click += new EventHandler(menu_item_Click);
                contextMenuTray.Items.Insert(0, menu_item);
            }

            Text = Localization.Localize(Text) + ' ' + Localization.Localize("version") + ' ' + Program.ApplicationVersion;
            notifyIcon.Text = Text;
            pageAbout.Text = Localization.Localize(pageAbout.Text);
            pageSettings.Text = Localization.Localize(pageSettings.Text);
            pageProfiles.Text = Localization.Localize(pageProfiles.Text);
            checkBoxShowBalloon.Text = Localization.Localize(checkBoxShowBalloon.Text);
            labelBalloonTimeout.Text = Localization.Localize(labelBalloonTimeout.Text);
            labelBalloonClickAction.Text = Localization.Localize(labelBalloonClickAction.Text);
            checkBoxShowToolTip.Text = Localization.Localize(checkBoxShowToolTip.Text);
            labelToolTipTimeout.Text = Localization.Localize(labelToolTipTimeout.Text);
            checkBoxShowForm.Text = Localization.Localize(checkBoxShowForm.Text);
            checkBoxFormTopMost.Text = Localization.Localize(checkBoxFormTopMost.Text);
            linkLabelDefaultLocation.Text = Localization.Localize(linkLabelDefaultLocation.Text);
            menuItemHtmlWordWrap.Text = Localization.Localize(menuItemHtmlWordWrap.Text);
            checkBoxDoubleCopyToClipboard.Text = Localization.Localize(checkBoxDoubleCopyToClipboard.Text);
            checkBoxAutoRun.Text = Localization.Localize(checkBoxAutoRun.Text);
            labelDeveloper.Text = Localization.Localize(labelDeveloper.Text);
            linkLabelSendEmail.Text = Localization.Localize(linkLabelSendEmail.Text);
            groupBoxSource.Text = Localization.Localize(groupBoxSource.Text);
            groupBoxResult.Text = Localization.Localize(groupBoxResult.Text);
            groupBoxPreview.Text = Localization.Localize(groupBoxPreview.Text);
            menuItemExit.Text = Localization.Localize(menuItemExit.Text);
            menuItemShowMainForm.Text = Localization.Localize(menuItemShowMainForm.Text);
            menuItemShowResultForm.Text = Localization.Localize(menuItemShowResultForm.Text);
            checkBoxShowInTaskbar.Text = Localization.Localize(checkBoxShowInTaskbar.Text);
            menuItemRemoveClassName.Text = Localization.Localize(menuItemRemoveClassName.Text);
            checkBoxClearBeforeNavigate.Text = Localization.Localize(checkBoxClearBeforeNavigate.Text);

            foreach (string action in Enum.GetNames(typeof(BalloonClickAction)))
            {
                FieldInfo field_info = typeof(BalloonClickAction).GetField(action);
                DescriptionAttribute description = Attribute.GetCustomAttribute(field_info, typeof(DescriptionAttribute)) as DescriptionAttribute;
                comboBoxBalloonClickAction.Items.Add(Localization.Localize(description.Description));
            }
            
            should_save = false;
            checkBoxShowBalloon.Checked = settings.ShowBalloon;
            textBoxBalloonTimeout.Text = settings.BalloonTimeout.ToString();
            checkBoxShowToolTip.Checked = settings.ShowToolTip;
            textBoxToolTipTimeout.Text = settings.ToolTipTimeout.ToString();
            checkBoxShowForm.Checked = settings.ShowForm;
            checkBoxFormTopMost.Checked = settings.FormTopMost;
            textBoxResult.WordWrap = menuItemHtmlWordWrap.Checked = settings.HtmlWordWrap;
            checkBoxDoubleCopyToClipboard.Checked = settings.DoubleCopyToClipboard;
            comboBoxBalloonClickAction.SelectedIndex = (int)settings.BalloonClickActionValue;
            checkBoxAutoRun.Checked = AutoRun.Enabled;
            MinimizeBox = ShowInTaskbar = checkBoxShowInTaskbar.Checked = settings.ShowInTaskbar;
            should_save = true;

            linkLabelApplicationFolder.Text = Program.ApplicationFolder;
            linkLabelUserDataFolder.Text = Program.UserDataFolder;

            comboBoxProfile.Select(settings.SelectedProfile);

            next_clipboard_viewer = SetClipboardViewer(Handle);

            string info_path = Program.ApplicationFolder + Path.DirectorySeparatorChar + Localization.Language + ".txt";
            if (File.Exists(info_path))
            {
                FileStream file = new FileStream(info_path, FileMode.Open, FileAccess.Read);
                StreamReader reader = new StreamReader(file);
                textBoxInfo.Text = reader.ReadToEnd();
                reader.Close();
            }
        }

        void LoadUserProfiles(List<string> profiles)
        {
            foreach (FileInfo file in new DirectoryInfo(Program.UserDataFolder).GetFiles("*.ct"))
                profiles.Add(Path.GetFileNameWithoutExtension(file.Name));
        }

        void LoadApplicationProfiles(List<string> profiles)
        {
            foreach (FileInfo file in new DirectoryInfo(Program.ApplicationFolder).GetFiles("*.ct"))
            {
                string profile = Path.GetFileNameWithoutExtension(file.Name);
                if (!profiles.Contains(profile))
                {
                    File.Copy(file.FullName, Program.UserDataFolder + Path.DirectorySeparatorChar + file.Name);
                    profiles.Add(profile);
                }
            }
        }

        string GetFilePath(string item)
        {
            return Program.UserDataFolder + Path.DirectorySeparatorChar + item + ".ct";
        }

        void SaveProfile()
        {
            FileStream file = new FileStream(GetFilePath(comboBoxProfile.Text), FileMode.Create, FileAccess.ReadWrite);
            StreamWriter writer = new StreamWriter(file, Encoding.Unicode);
            writer.WriteLine("3");
            writer.WriteLine(checkBoxClearBeforeNavigate.Checked.ToString());
            writer.WriteLine(textBoxPrefix.Text);
            writer.WriteLine(textBoxPostfix.Text);
            foreach(string class_name in listBoxClasses.Items)
                writer.WriteLine(class_name);
            writer.Flush();
            writer.Close();
        }

        private void comboBoxProfile_OnNewItem()
        {
            SaveProfile();
            ToolStripMenuItem menu_item = new ProfileToolStripMenuItem(comboBoxProfile.Text);
            menu_item.Click += new EventHandler(menu_item_Click);
            contextMenuTray.Items.Insert(0, menu_item);
        }

        private void comboBoxProfile_OnRemoveItem()
        {
            File.Delete(GetFilePath(comboBoxProfile.Text));
            foreach (ToolStripItem menu_item in contextMenuTray.Items)
                if (menu_item is ProfileToolStripMenuItem && comboBoxProfile.Text == (menu_item as ToolStripMenuItem).Text)
                {
                    contextMenuTray.Items.Remove(menu_item);
                    break;
                }
        }

        private void comboBoxProfile_OnSelectItem()
        {
            listBoxClasses.Items.Clear();
            FileStream file = new FileStream(GetFilePath(comboBoxProfile.Text), FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(file);
            int version = int.Parse(reader.ReadLine());
            if (3 == version)
            {
                checkBoxClearBeforeNavigate.Checked = bool.Parse(reader.ReadLine());
                textBoxPrefix.Text = reader.ReadLine();
                textBoxPostfix.Text = reader.ReadLine();
                while (!reader.EndOfStream)
                    listBoxClasses.Items.Add(reader.ReadLine());
                Navigate();
            }
            reader.Close();

            settings.SelectedProfile = comboBoxProfile.Text;
            settings.Save();

            foreach (ToolStripItem menu_item in contextMenuTray.Items)
                if (menu_item is ProfileToolStripMenuItem)
                    (menu_item as ToolStripMenuItem).Checked = menu_item.Text == comboBoxProfile.Text;
        }

        private void comboBoxProfile_OnSaveItem()
        {
            SaveProfile();
        }

        bool Editing { get { return treeViewHtml.Focused || textBoxPrefix.Focused || textBoxPostfix.Focused || comboBoxText.Focused; } }

        protected override void WndProc(ref Message m)
        {
            if (WM_CHANGECBCHAIN == m.Msg)
            {
                if (m.WParam == next_clipboard_viewer)
                    next_clipboard_viewer = m.LParam;
                else
                    SendMessage(next_clipboard_viewer, m.Msg, m.WParam, m.LParam);

            }
            else if (WM_DRAWCLIPBOARD == m.Msg)
            {
                if (!Editing)
                {
                    string clipboard_text = Clipboard.GetText(TextDataFormat.UnicodeText).Trim(' ', ',', '.', ':', ';', '!', '?', '(', ')', '\'', '\"');
                    if (!string.IsNullOrEmpty(clipboard_text))
                    {
                        int copy_to_clipboard_interval = Environment.TickCount - last_copy_to_clipboard_tick_count;
                        last_copy_to_clipboard_tick_count = Environment.TickCount;
                        if (settings.DoubleCopyToClipboard)
                        {
                            if (prev_clipboard_text == clipboard_text && copy_to_clipboard_interval < double_copy_to_clipboard_interval)
                            {
                                comboBoxText.Text = prev_clipboard_text = "";
                                comboBoxText.Text = clipboard_text;
                            }
                            else prev_clipboard_text = clipboard_text;
                        }
                        else
                            comboBoxText.Text = clipboard_text;
                    }
                }
                m.Result = IntPtr.Zero;
            }
            else base.WndProc(ref m);
        }

        void Navigate()
        {
            if (!string.IsNullOrEmpty(textBoxPrefix.Text) && !string.IsNullOrEmpty(comboBoxText.Text))
            {
                webBrowser.Stop();
                if (checkBoxClearBeforeNavigate.Checked && null != webBrowser.Document)
                    webBrowser.Document.Write(" ");
                url = textBoxPrefix.Text + comboBoxText.Text + textBoxPostfix.Text;
                webBrowser.Navigate(url);
            }
        }

        private void textUrl_TextChanged(object sender, EventArgs e)
        {
            if(!Editing)
                Navigate();
        }

        private void comboBoxText_SelectedIndexChanged(object sender, EventArgs e)
        {
            Navigate();
        }

        void HtmlElementToTreeNodeCollection(HtmlElement html, TreeNodeCollection node_collection)
        {
            HtmlTreeNode node = new HtmlTreeNode(html);
            node.Checked = listBoxClasses.Items.Contains(node.ClassName);
            node_collection.Add(node);
            if (html.CanHaveChildren)
                foreach (HtmlElement i in html.Children)
                    HtmlElementToTreeNodeCollection(i, node.Nodes);
        }

        private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            treeViewHtml.Nodes.Clear();
            if (Visible && FormWindowState.Minimized != WindowState)
            {
                HtmlElementToTreeNodeCollection(webBrowser.Document.Body, treeViewHtml.Nodes);
            }
            Translate();
        }

        void ExpandNode(TreeNode node)
        {
            if (null != node.Parent)
                ExpandNode(node.Parent);
            node.Expand();
        }

        void ExpandHtmlTreeNode(TreeNodeCollection node_collection, string class_name)
        {
            foreach (HtmlTreeNode node in node_collection)
            {
                if (node.ClassName == class_name)
                    ExpandNode(node);
                ExpandHtmlTreeNode(node.Nodes, class_name);
            }
        }

        private void listBoxClasses_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (null != listBoxClasses.SelectedItem)
                ExpandHtmlTreeNode(treeViewHtml.Nodes, listBoxClasses.SelectedItem as string);
        }

        private void treeViewHtml_AfterSelect(object sender, TreeViewEventArgs e)
        {
            HtmlTreeNode node = e.Node as HtmlTreeNode;
            textBoxResult.Text = node.Html.OuterHtml;
        }

        private void treeViewHtml_BeforeCheck(object sender, TreeViewCancelEventArgs e)
        {
            HtmlTreeNode node = e.Node as HtmlTreeNode;
            e.Cancel = string.IsNullOrEmpty(node.ClassName);
        }

        private void treeViewHtml_AfterCheck(object sender, TreeViewEventArgs e)
        {
            HtmlTreeNode node = e.Node as HtmlTreeNode;
            if (node.Checked)
            {
                if (!listBoxClasses.Items.Contains(node.ClassName))
                    listBoxClasses.Items.Add(node.ClassName);
            }
            else
            {
                if (listBoxClasses.Items.Contains(node.ClassName))
                    listBoxClasses.Items.Remove(node.ClassName);
            }
            Translate();
        }

        HtmlElement[] Transform(HtmlElement html)
        {
            List<HtmlElement> result = new List<HtmlElement>();
            string class_name = html.GetAttribute("className");
            if (listBoxClasses.Items.Contains(class_name))
                result.Add(html);
            else if (html.CanHaveChildren)
                foreach (HtmlElement i in html.Children)
                    result.AddRange(Transform(i));
            return result.ToArray();
        }

        string Transform()
        {
            HtmlElement[] html = Transform(webBrowser.Document.Body);
            string result = "";
            foreach (HtmlElement i in html)
                result += i.OuterHtml;
            return result;
        }

        void Translate()
        {
            if (!string.IsNullOrEmpty(url))
            {
                textBoxResult.Text = "";
                textBoxResult.Text = Transform();
            }
        }

        private void textBoxResult_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBoxResult.Text))
                notifyIcon.Icon = Properties.Resources.RedIcon;
            else
            {
                notifyIcon.Icon = Properties.Resources.MainIcon;
                if (!string.IsNullOrEmpty(webBrowserResult.DocumentText))
                    webBrowserResult.Stop();
                result_link_clicked = false;
                webBrowserResult.DocumentText = textBoxResult.Text;
            }
        }

        void SaveToRuntimeHistory()
        {
            if (Translated)
                if (!comboBoxText.Items.Contains(comboBoxText.Text))
                {
                    if (comboBoxText.Items.Count >= settings.RuntimeHistoryMaxCount)
                        comboBoxText.Items.RemoveAt(0);
                    comboBoxText.Items.Add(comboBoxText.Text);
                }
        }

        private void webBrowserResult_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            foreach (HtmlElement link in webBrowserResult.Document.Links)
                link.Click += new HtmlElementEventHandler(link_Click);

            notifyIcon.Icon = Translated ? Properties.Resources.GreenIcon : Properties.Resources.RedIcon;
            
            if(settings.ShowBalloon) 
                ShowBalloon();

            if (settings.ShowToolTip)
                ShowToolTip();

            if (settings.ShowForm || null != result_form)
                ShowForm();

            SaveToRuntimeHistory();
        }

        void link_Click(object sender, HtmlElementEventArgs e)
        {
            result_link_clicked = true;
        }

        private void webBrowserResult_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            if (result_link_clicked)
            {
                e.Cancel = true;
                Process.Start(url);
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = !can_close && CloseReason.WindowsShutDown != e.CloseReason && FormWindowState.Minimized != WindowState;
            if (e.Cancel)
            {
                if (ShowInTaskbar)
                    WindowState = FormWindowState.Minimized;
                else if (Visible)
                    Visible = false;
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            ChangeClipboardChain(next_clipboard_viewer);
        }

        private void webBrowser_NewWindow(object sender, CancelEventArgs e)
        {
            e.Cancel = true;
        }

        private void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            switch (settings.BalloonClickActionValue)
            {
                case BalloonClickAction.ShowForm: ShowForm(); break;
                case BalloonClickAction.ShowToolTip: ShowToolTip(); break;
                case BalloonClickAction.ShowWebPage: Process.Start(balloon_url); break;
            }
        }

        bool Translated { get { return null != webBrowserResult.Document && !string.IsNullOrEmpty(webBrowserResult.Document.Body.InnerText); } }

        bool Navigated { get { return null != webBrowser.Document && !string.IsNullOrEmpty(webBrowser.Document.Body.InnerText); } }

        void ShowBalloon()
        {
            if (Translated)
            {
                notifyIcon.BalloonTipTitle = comboBoxText.Text;
                notifyIcon.BalloonTipText = webBrowserResult.Document.Body.InnerText;
                balloon_url = url;
                notifyIcon.Text = url.Length < 63 ? url : url.Substring(0, 63);
                notifyIcon.ShowBalloonTip(settings.BalloonTimeout * 1000);
            }
        }

        void ShowToolTip()
        {
            DesktopToolTip.Show(webBrowserResult.Document.Body.InnerText, comboBoxText.Text, settings.ToolTipTimeout * 1000);
        }

        void ShowForm()
        {
            if (default_location && null != result_form)
                result_form.Close();

            if (null == result_form)
            {
                result_form = new ResultForm(this, default_location);
                result_form.FormClosed += new FormClosedEventHandler(result_form_FormClosed);
                result_form.Show();
            }

            result_form.Navigate(url, comboBoxText.Text, webBrowserResult.DocumentText);

            default_location = false;
        }

        void result_form_FormClosed(object sender, FormClosedEventArgs e)
        {
            result_form = null;
        }

        private void checkBoxShowBalloon_CheckedChanged(object sender, EventArgs e)
        {
            settings.ShowBalloon = checkBoxShowBalloon.Checked;
            SaveSettings();
        }

        private void textBoxBalloonTimeout_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(textBoxBalloonTimeout.Text))
            {
                int timeout;
                if (int.TryParse(textBoxBalloonTimeout.Text, out timeout))
                {
                    settings.BalloonTimeout = timeout;
                    SaveSettings();
                }
                else textBoxBalloonTimeout.Text = settings.BalloonTimeout.ToString();
            }
        }

        private void comboBoxBalloonClickAction_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxBalloonClickAction.SelectedIndex >= 0)
            {
                settings.BalloonClickActionValue = (BalloonClickAction)comboBoxBalloonClickAction.SelectedIndex;
                settings.Save();
            }
        }

        private void checkBoxShowToolTip_CheckedChanged(object sender, EventArgs e)
        {
            settings.ShowToolTip = checkBoxShowToolTip.Checked;
            SaveSettings();
        }

        private void textBoxToolTipTimeout_TextChanged(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(textBoxToolTipTimeout.Text))
            {
                int timeout;
                if (int.TryParse(textBoxToolTipTimeout.Text, out timeout))
                {
                    settings.ToolTipTimeout = timeout;
                    SaveSettings();
                }
                else textBoxToolTipTimeout.Text = settings.ToolTipTimeout.ToString();
            }
        }

        private void checkBoxShowForm_CheckedChanged(object sender, EventArgs e)
        {
            settings.ShowForm = checkBoxShowForm.Checked;
            SaveSettings();
        }

        private void checkBoxFormTopMost_CheckedChanged(object sender, EventArgs e)
        {
            settings.FormTopMost = checkBoxFormTopMost.Checked;
            SaveSettings();
        }

        private void menuItemHtmlWordWrap_Click(object sender, EventArgs e)
        {
            textBoxResult.WordWrap = settings.HtmlWordWrap = menuItemHtmlWordWrap.Checked;
            SaveSettings();
        }

        private void checkBoxDoubleCopyToClipboard_CheckedChanged(object sender, EventArgs e)
        {
            settings.DoubleCopyToClipboard = checkBoxDoubleCopyToClipboard.Checked;
            SaveSettings();
        }

        private void checkBoxAutoRun_CheckedChanged(object sender, EventArgs e)
        {
            AutoRun.Enabled = checkBoxAutoRun.Checked;
        }

        private void checkBoxShowInTaskbar_CheckedChanged(object sender, EventArgs e)
        {
            MinimizeBox = ShowInTaskbar = settings.ShowInTaskbar = checkBoxShowInTaskbar.Checked;
            settings.Save();
        }

        void SaveSettings()
        {
            if (should_save)
                settings.Save();
        }

        private void linkLabelDefaultLocation_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            default_location = true;
        }

        void menu_item_Click(object sender, EventArgs e)
        {
            comboBoxProfile.Select((sender as ToolStripMenuItem).Text);
        }

        private void linkLabelSendEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process.Start("mailto:" + Program.MailTo);
        }

        private void linkLabelFolder_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ProcessStartInfo info = new ProcessStartInfo("explorer");
            info.Arguments = '"' + (sender as LinkLabel).Text + '"';
            Process process = Process.Start(info);
        }

        private void notifyIcon_DoubleClick(object sender, EventArgs e)
        {
            ShowForm();
        }

        private void menuItemShowMainForm_Click(object sender, EventArgs e)
        {
            if (ShowInTaskbar)
                WindowState = FormWindowState.Normal;
            else if (!Visible)
                Visible = true;
            BringToFront();
        }

        private void menuItemShowResultForm_Click(object sender, EventArgs e)
        {
            ShowForm();
        }

        private void menuItemExit_Click(object sender, EventArgs e)
        {
            can_close = true;
            Close();
        }

        private void MainForm_VisibleChanged(object sender, EventArgs e)
        {
            if (loading)
                Visible = settings.Visible;
            else
            {
                settings.Visible = Visible;
                settings.Save();
            }
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            loading = false;
            WindowState = settings.Minimized ? FormWindowState.Minimized : FormWindowState.Normal;
        }

        private void MainForm_ClientSizeChanged(object sender, EventArgs e)
        {
            if (last_window_state != WindowState)
            {
                last_window_state = WindowState;
                bool minimized = FormWindowState.Minimized == WindowState;
                if (minimized != settings.Minimized)
                {
                    settings.Minimized = minimized;
                    settings.Save();
                }
            }
        }

        private void webBrowser_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
        {
            if (e.MaximumProgress > 0 && e.CurrentProgress >= 0 && e.MaximumProgress > e.CurrentProgress)
            {
                FlashWindow(Handle, true);
                notifyIcon.Tag = !(bool)notifyIcon.Tag;
                notifyIcon.Icon = (bool)notifyIcon.Tag ? Properties.Resources.YellowIcon : Properties.Resources.MainIcon;
            }
        }

        private void contextMenuTree_Opening(object sender, CancelEventArgs e)
        {
            e.Cancel = null == listBoxClasses.SelectedItem;
        }

        private void menuItemRemoveClassName_Click(object sender, EventArgs e)
        {
            listBoxClasses.Items.Remove(listBoxClasses.SelectedItem);
        }
    }

    public interface IScript
    {
        string Transform(string html);
    }

    class ProfileToolStripMenuItem : ToolStripMenuItem
    {
        public ProfileToolStripMenuItem(string text)
            : base(text)
        {
        }
    }

    class HtmlTreeNode : TreeNode
    {
        HtmlElement html;
        
        string class_name;

        public string ClassName { get { return class_name; } }

        public HtmlElement Html { get { return html; } }

        public HtmlTreeNode(HtmlElement html)
        {
            this.html = html;
            Text = html.TagName;
            class_name = html.GetAttribute("className");
            if (!string.IsNullOrEmpty(class_name))
                Text += ' ' + class_name;
        }
    }
}
